﻿--Macaroon, a World of Warcraft® user interface addon.
--Copyright© 2008 Connor H. Chenoweth, aka Maul

local barShapes = {
	[1] = MACAROON_STRINGS.BARSHAPE_1,
	[2] = MACAROON_STRINGS.BARSHAPE_2,
	[3] = MACAROON_STRINGS.BARSHAPE_3,
}

local barStates = {
	[1] = { "pagedbar" },
	[2] = { "stance" },
	[3] = { "pet" },
	[4] = { "stealth" },
	[5] = { "reaction" },
	[6] = { "combat" },
	[7] = { "group" },
	[8] = { "possess" },
	[9] = { "alt" },
	[10] = { "ctrl" },
	[11] = { "shift" },
	[12] = { "custom" },
}

local toggleStates = {
	autoHide = MACAROON_STRINGS.BARSTATE_AH,
	showGrid = MACAROON_STRINGS.BARSTATE_SG,
	snapTo = MACAROON_STRINGS.BARSTATE_ST,
	hidden = MACAROON_STRINGS.BARSTATE_HD,
}

local alphaUpValues = {
	[1] = MACAROON_STRINGS.ALPHAUP_NONE,
	[2] = MACAROON_STRINGS.ALPHAUP_BATTLE,
	[3] = MACAROON_STRINGS.ALPHAUP_MOUSEOVER,
	[4] = MACAROON_STRINGS.ALPHAUP_BATTLEMOUSE,
	[5] = MACAROON_STRINGS.ALPHAUP_RETREAT,
	[6] = MACAROON_STRINGS.ALPHAUP_RETREATMOUSE,
}

local frameStratas = { "BACKGROUND", "LOW", "MEDIUM", "HIGH", "DIALOG", "TOOLTIP" }

local arcPresets = {
	[1] = { MACAROON_STRINGS.ARC_PRESET_1, 173, 180 },
	[2] = { MACAROON_STRINGS.ARC_PRESET_2, 353, 180 },
	[3] = { MACAROON_STRINGS.ARC_PRESET_3, 262, 180 },
	[4] = { MACAROON_STRINGS.ARC_PRESET_4, 82, 180 },
	[5] = { MACAROON_STRINGS.ARC_PRESET_5, 90, 360 },
}

local targetNames = { "-none-", "player", "pet", "target", "targettarget", "focus", "focustarget", "mouseover", "party1", "party2", "party3", "party4" }

local editMode, ss, playerEnteredWorld = false

local find = string.find
local lower = string.lower
local format = string.format
local gsub = string.gsub
local match = string.match
local strlen = strlen

local GetMouseFocus = _G.GetMouseFocus

local spellIndex = Macaroon.spellIndex
local managedStates = Macaroon.managedStates
local clearTable = Macaroon.clearTable
local MACAROON_STRINGS = MACAROON_STRINGS

local ssdmUpdate = SecureStateDriverManager:GetScript("OnEvent")

Macaroon.CurrentBar = nil

local function getBindkeyList(bar)

	local bindkeys = gsub(bar.config.hotKeyText, "_", ", ")

	bindkeys = gsub(bindkeys, "^, ", "")
	bindkeys = gsub(bindkeys, ", $", "")

	if (strlen(bindkeys) < 1) then
		bindkeys = MACAROON_STRINGS.KEYBIND_NONE
	end

	return bindkeys
end

local function getStateList(bar)

	local states = ""

	for state,values in pairs(managedStates) do
		for k,v in pairs(barStates) do
			if (bar.config[state] and v[1] == state) then
				states = states..v[2]..", "
			end
		end
	end

	states = gsub(states, ", $", "")

	if (strlen(states) < 1) then
		states = MACAROON_STRINGS.KEYBIND_NONE
	end

	return states
end

local function updateButtonCount(bar, delta)

	if (delta > 0) then
		Macaroon.AddButton()
	else
		Macaroon.RemoveButton()
	end

	bar.updateBar(bar, nil, true, true)
end

local function updateScale(bar, delta)

	if (delta > 0) then
		bar.config.scale = bar.config.scale + 0.01
	else
		bar.config.scale = bar.config.scale - 0.01
		if (bar.config.scale < 0.2) then
			bar.config.scale = 0.2
		end
	end

	bar.updateBar(bar, nil, true, true)
end

local function updateStratas(bar, delta)

	local currStrata = 1

	for k,v in pairs(frameStratas) do
		if (bar.config.buttonStrata == v) then
			currStrata = k
		end
	end

	if (delta > 0) then

		if (currStrata >= 5) then
			bar.config.buttonStrata = frameStratas[5]
			bar.config.barStrata = frameStratas[6]
		else
			bar.config.buttonStrata = frameStratas[currStrata+1]
			bar.config.barStrata = frameStratas[currStrata+2]
		end
	else

		if (currStrata <= 1) then
			bar.config.buttonStrata = frameStratas[1]
			bar.config.barStrata = frameStratas[2]
		else
			bar.config.buttonStrata = frameStratas[currStrata-1]
			bar.config.barStrata = frameStratas[currStrata]
		end
	end

	bar.updateBar(bar, true, true)
end

local function updateAlpha(bar, delta)

	if (delta > 0) then
		bar.config.alpha = bar.config.alpha + 0.05
		if (bar.config.alpha > 1) then
			bar.config.alpha = 1
		end
	else
		bar.config.alpha = bar.config.alpha - 0.05
		if (bar.config.alpha < 0) then
			bar.config.alpha = 0
		end
	end

	bar.updateBar(bar, true)
end

local function updateAlphaUp(bar, delta)

	local currValue = 1

	for k,v in pairs(alphaUpValues) do
		if (bar.config.alphaUp == v) then
			currValue = k
		end
	end

	if (delta > 0) then

		currValue = currValue + 1

		if (currValue > #alphaUpValues) then
			currValue = #alphaUpValues
		end

		bar.config.alphaUp = alphaUpValues[currValue]

	else

		currValue = currValue - 1

		if (currValue < 1) then
			currValue = 1
		end

		bar.config.alphaUp = alphaUpValues[currValue]
	end

	bar.updateBar(bar, true)
end

local function updateShape(bar, delta)

	if (delta > 0) then

		bar.config.shape = bar.config.shape + 1

		if (bar.config.shape > #barShapes) then
			bar.config.shape = #barShapes
		end
	else

		bar.config.shape = bar.config.shape - 1

		if (bar.config.shape < 1) then
			bar.config.shape = 1
		end
	end

	bar.updateBar(bar, nil, true, true)
end

local function updateColumns(bar, delta)

	if (delta > 0) then

		bar.config.columns = bar.config.columns + 1

	else
		bar.config.columns = bar.config.columns - 1

		if (bar.config.columns < 1) then
			bar.config.columns = 1
		end
	end

	bar.updateBar(bar, nil, true, true)

end

local function updateArcStart(bar, delta)

	if (delta > 0) then

		bar.config.arcStart = bar.config.arcStart + 1

		if (bar.config.arcStart > 360) then
			bar.config.arcStart = 1
		end
	else

		bar.config.arcStart = bar.config.arcStart - 1

		if (bar.config.arcStart < 1) then
			bar.config.arcStart = 360
		end
	end

	bar.updateBar(bar, nil, true, true)

end

local function updateArcLength(bar, delta)

	if (delta > 0) then

		bar.config.arcLength = bar.config.arcLength + 1

		if (bar.config.arcLength > 360) then
			bar.config.arcLength = 1
		end
	else

		bar.config.arcLength = bar.config.arcLength - 1

		if (bar.config.arcLength < 1) then
			bar.config.arcLength = 360
		end
	end

	bar.updateBar(bar, nil, true, true)

end

local function updateArcPreset(bar, delta)

	local index = 5

	for k,v in pairs(arcPresets) do
		if (v[2] == bar.config.arcStart) then
			index = k
		end
	end

	if (delta > 0) then

		index = index + 1

		if (index > #arcPresets) then
			index = 1
		end
	else

		index = index - 1

		if (index < 1) then
			index = #arcPresets
		end
	end

	bar.config.arcStart = arcPresets[index][2]
	bar.config.arcLength = arcPresets[index][3]

	bar.updateBar(bar, nil, true, true)
end

local function updatePadH(bar, delta)

	if (delta > 0) then
		bar.config.padH = bar.config.padH + 0.5
	else
		bar.config.padH = bar.config.padH - 0.5
	end

	bar.updateBar(bar, nil, true, true)
end

local function updatePadV(bar, delta)

	if (delta > 0) then
		bar.config.padV = bar.config.padV + 0.5
	else
		bar.config.padV = bar.config.padV - 0.5
	end

	bar.updateBar(bar, nil, true, true)

end

local function updatePadHV(bar, delta)

	if (delta > 0) then
		bar.config.padH = bar.config.padH + 0.5
		bar.config.padV = bar.config.padV + 0.5
	else
		bar.config.padH = bar.config.padH - 0.5
		bar.config.padV = bar.config.padV - 0.5
	end

	bar.updateBar(bar, nil, true, true)
end

--updateBar(bar, options, shape, size, pos)

local actionTable = {
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_1] = updateScale,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_2] = updateShape,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_3] = updateColumns,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_4] = updateStratas,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_5] = updateAlpha,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_6] = updateAlphaUp,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_7] = updateArcStart,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_8] = updateArcLength,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_9] = updateArcPreset,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_10] = updatePadH,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_11] = updatePadV,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_12] = updatePadHV,
	[MACAROON_STRINGS.BAR_EDIT_BUTTON_13] = updateButtonCount,
}


local cycleOrder = {}

local stateOrder = {
	[1] = "pet1",
	[2] = "pet2",
	[3] = "stealth1",
	[4] = "reaction1",
	[5] = "combat1",
	[6] = "group1",
	[7] = "group2",
	[8] = "possess1",
	[9] = "alt1",
	[10] = "ctrl1",
	[11] = "shift1",
}

local function updateCycleOrder(bar)

	clearTable(cycleOrder)

	local index = 1

	cycleOrder[index] = "homestate"
	index = index + 1

	for i=1,NUM_ACTIONBAR_PAGES do
		cycleOrder[index] = "pagedbar"..i
		index = index + 1
	end

	if (UnitClass("player") ~= MACAROON_STRINGS.WARRIOR and GetNumShapeshiftForms() ~= 0) then
		cycleOrder[index] = "stance0"
		index = index + 1
	end

	for i=1,GetNumShapeshiftForms() do
		cycleOrder[index] = "stance"..i
		index = index + 1
	end

	if (bar.config.prowl) then
		cycleOrder[index] = "stance8"
		index = index + 1
	end

	for k,v in ipairs(stateOrder) do
		cycleOrder[index] = v
		index = index + 1
	end

	if (bar.config.custom and bar.config.customRange) then

		local start = tonumber(match(bar.config.customRange, "^%d+"))
		local stop = tonumber(match(bar.config.customRange, "%d+$"))

		if (start and stop) then
			for i=start,stop do
				cycleOrder[index] = "custom"..i
				index = index + 1
			end
		end
	end
end

local function updateState(bar, delta)

	local currState, homestate = bar.handler:GetAttribute("state-current"), bar.handler:GetAttribute("state-homestate")
	local range, newState, index, found = 1

	for k,v in ipairs(cycleOrder) do
		if (v == currState) then
			index = k
		end
	end

	if (index) then

		local count = 1

		while (not found and count <= #cycleOrder) do

			if (delta > 0) then

				index = index + 1

				if (index > #cycleOrder) then
					index = range
				end
			else
				index = index - 1

				if (index < range) then
					index = #cycleOrder
				end
			end

			newState = match(cycleOrder[index], "%a+")

			if (bar.config[newState]) then

				newState = cycleOrder[index]

				if (newState == homestate) then
					count = count - 1
				else
					found = true
				end
			end

			count = count + 1
		end
	end

	bar.handler:SetAttribute("state-current", newState)
	bar.updateBar(bar, nil, true, true)
end

local function updateValues(bar, delta, action)

	if (actionTable[action]) then
		actionTable[action](bar, delta)
	end
end

function Macaroon.ConfigBars(off, on)

	if (not off) then
		Macaroon.ButtonEdit(true)
		Macaroon.ButtonBind(true)
	end

	if ((editMode or off) and not on) then

		for k,v in pairs(Macaroon.BarIndex) do
			v:Hide()
		end

		Macaroon.ChangeBar()

		editMode = false

		if (not off) then
			for k,v in pairs(Macaroon.HideGrids) do
				v(true)
			end
		end

		MacaroonBarEditor.shrink = true
		MacaroonBarTextEditor.shrink = true

		for k,v in pairs(Macaroon.StatesToSave) do v() end

	else

		for k,v in pairs(Macaroon.BarIndex) do
			v:Show()
		end

		editMode = true

		if (not off) then
			for k,v in pairs(Macaroon.ShowGrids) do
				v(true)
			end
		end
	end
end

function Macaroon.ChangeBar(self)

	local newBar = false

	if (playerEnteredWorld) then

		if (self and Macaroon.CurrentBar ~= self) then

			newBar = true
			Macaroon.CurrentBar = self
			self.selected = true
			self.action = nil

			if (self.config.hidden) then
				self:SetBackdropColor(1,0,0,0.6)
			else
				self:SetBackdropColor(0,0,1,0.4)
			end

			updateCycleOrder(self)
		end

		if (not self) then
			Macaroon.CurrentBar = nil
		else
			self.text:Show()
		end

		for k,v in pairs(Macaroon.BarIndex) do
			if (v ~= self) then

				if (v.config.hidden) then
					v:SetBackdropColor(1,0,0,0.4)
				else
					v:SetBackdropColor(0,0,0,0.2)
				end

				v:SetBackdropBorderColor(0.3,0.3,0.3,0.3)
				v.selected = false
				v.microAdjust = false
				v:EnableKeyboard(false)
				v.text:Hide()
				v.message:SetText("")
				v.mousewheelfunc = nil
				v.action = nil
			end
		end
	end

	return newBar
end

function Macaroon.Bar_OnLoad(self)

	self:RegisterForClicks("AnyDown", "AnyUp")
	self:RegisterForDrag("LeftButton")
	self:RegisterEvent("PLAYER_LOGIN")
	self:RegisterEvent("PLAYER_ENTERING_WORLD")
	self:SetBackdropColor(0,0,0,0.2)
	self:SetBackdropBorderColor(0.3,0.3,0.3,0.3)
	self:EnableKeyboard(false)
	self:SetFrameLevel(2)

	self.elapsed = 0
	self.click = nil
	self.dragged = false
	self.selected = false
	self.toggleframe = self
	self.microAdjust = false
	self.bindframe = _G[self:GetName().."KeyBind"]
	self.text = _G[self:GetName().."Text"]
	self.message = _G[self:GetName().."Message"]
	self.message:SetHeight(50)
	self.snapTo = _G[self:GetName().."SnapTo"]
	self.snapTo:SetBackdropColor(1,0,0,0.3)
	self.snapTo:SetBackdropBorderColor(0,0,0,0)

	_G[self:GetName().."Text"]:Hide()
end

function Macaroon.Bar_OnEvent(self, event)

end

function Macaroon.Bar_OnClick(self, click, down)

	if (not down) then
		self.newBar = Macaroon.ChangeBar(self)
	end

	self.click = click
	self.dragged = false
	self.elapsed = 0
	self.pushed = 0

	if (click == "MiddleButton") then

		if (GetMouseFocus() ~= Macaroon.CurrentBar) then
			self.newBar = Macaroon.ChangeBar(self)
		end

		if (down) then

			if (self.action) then

				self.hover = nil
				self.elapsed = 1

			elseif (self.config.hidden) then

				self.config.hidden = false
				Macaroon.HideBar(nil, true, self.config.hidden)
			else
				self.config.hidden = true
				Macaroon.HideBar(nil, true, self.config.hidden)
			end
		end

	elseif (click == "RightButton" and not self.action and not down) then

		self.message:SetText("")

		self.mousewheelfunc = nil

		MacaroonBarEditor:ClearAllPoints()

		if (ss.checkButtons[202]) then
			MacaroonBarEditor:SetPoint("CENTER", MacaroonPanelMover, "CENTER")
		else
			MacaroonBarEditor:SetPoint("CENTER", self, "CENTER")
		end

		if (not self.newBar and (MacaroonBarEditor:IsVisible() or MacaroonBarTextEditor:IsVisible())) then

			MacaroonBarEditor.grow = false

			MacaroonBarTextEditor.grow = false

			MacaroonBarEditor.shrink = true

			MacaroonBarTextEditor.shrink = true
		else

			MacaroonBarEditor:Hide()

			MacaroonBarTextEditor.shrink = true

			MacaroonBarEditor:SetScale(0.01)

			MacaroonBarEditor.scale = 0.01

			MacaroonBarEditor.grow = true

			MacaroonBarEditor.shrink = false

			MacaroonBarEditor:Show()
		end

	elseif (not self.action and not down) then

		if (not self.newBar and not MacaroonBarEditor:IsVisible() and not MacaroonBarTextEditor:IsVisible()) then
			updateState(self, 1)
		end

		MacaroonBarEditor.grow = false

		MacaroonBarTextEditor.grow = false

		MacaroonBarEditor.shrink = true

		MacaroonBarTextEditor.shrink = true

		Macaroon.CurrentBar = self

	elseif (self.action and down) then

		if (click == "RightButton") then

			updateValues(self, -1, self.action)

		elseif (click == "LeftButton") then

			updateValues(self, 1, self.action)
		end

	end

	if (click ~= "MiddleButton") then
		Macaroon.Bar_OnEnter(self)
	end
end

function Macaroon.Bar_OnDragStart(self)

	Macaroon.ChangeBar(self)

	if (not self.action) then

		self:SetFrameStrata(self.config.barStrata)
		self:EnableKeyboard(false)

		self.adjusting = true
		self.selected = true
		self.isMoving = true

		self.config.snapToPoint = false
		self.config.snapToFrame = false

		self:StartMoving()
	end
end

function Macaroon.Bar_OnDragStop(self)

	if (not self.action) then

		local point

		self:StopMovingOrSizing()

		for k,v in pairs(Macaroon.BarIndex) do

			if (not point and self.config.snapTo and v.config.snapTo and self ~= v) then

				point = Macaroon.SnapTo.Stick(self, v, MacaroonSavedState.snapToTol, self.config.padH, self.config.padV)

				if (point) then
					self.config.snapToPoint = point
					self.config.snapToFrame = v:GetName()
					self.config.point = "SnapTo: "..point
					self.config.x = 0
					self.config.y = 0
				end
			end
		end

		if (not point) then
			self.config.snapToPoint = false
			self.config.snapToFrame = false
			self.config.point, self.config.x, self.config.y = Macaroon.GetPosition(self)
			Macaroon.SetPosition(self)
		end

		if (self.config.snapTo and not self.config.snapToPoint) then
			Macaroon.SnapTo.StickToEdge(self)
		end

		self.isMoving = false
		self.dragged = true
		self.elapsed = 0

		self.updateBar(self, nil, nil, nil, true)
	end
end

function Macaroon.Bar_OnKeyDown(self, key, onupdate)

	if (self.microAdjust and not self.action) then

		self.keydown = key

		if (not onupdate) then
			self.elapsed = 0
		end

		self.config.point, self.config.x, self.config.y = Macaroon.GetPosition(self)

		self:SetUserPlaced(false)

		self:ClearAllPoints()

		if (key == "UP") then
			self.config.y = self.config.y + .25
		elseif (key == "DOWN") then
			self.config.y = self.config.y - .25
		elseif (key == "LEFT") then
			self.config.x = self.config.x - .25
		elseif (key == "RIGHT") then
			self.config.x = self.config.x + .25
		end

		self:SetPoint("CENTER", "UIParent", "BOTTOMLEFT", self.config.x, self.config.y)

		self:SetUserPlaced(true)
	end
end

function Macaroon.Bar_OnKeyUp(self, key)

	if (not self.action) then

		self.keydown = nil
		self.elapsed = 0

		if (self.func1) then
			self.func1(self)
		end
	end
end

function Macaroon.Bar_OnEnter(self)

	if ( GetCVar("UberTooltips") == "1" ) then
		GameTooltip_SetDefaultAnchor(GameTooltip, self)
	else
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
	end

	GameTooltip:AddDoubleLine(self.config.name, "", 1.0, 1.0, 1.0)
	GameTooltip:AddDoubleLine(" ", " ")
	GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_3.."|cffffffff"..self.config.scale.."|r", MACAROON_STRINGS.BARTOOLTIP_4.."|cffffffff"..self.config.buttonStrata.."|r")
	GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_5.."|cffffffff"..self.config.alpha.."|r", MACAROON_STRINGS.BARTOOLTIP_6.."|cffffffff"..self.config.alphaUp.."|r")

	if (self.config.shape == 1) then

		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_7.."|cffffffff"..barShapes[self.config.shape], MACAROON_STRINGS.BARTOOLTIP_8.."|cffffffff"..self.config.columns.."|r")

	elseif (self.config.shape == 2 or self.config.shape == 3) then

		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_7.."|cffffffff"..barShapes[self.config.shape], MACAROON_STRINGS.BARTOOLTIP_9.."|cffffffff"..self.config.arcStart.."|r"..MACAROON_STRINGS.BARTOOLTIP_10.."|cffffffff"..self.config.arcLength.."|r")

	else
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_7.."|cffffffff"..barShapes[self.config.shape])
	end

	GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_11.."|cffffffff"..self.config.padH.."|r", MACAROON_STRINGS.BARTOOLTIP_12.."|cffffffff"..self.config.padV.."|r")

	if (self.config.snapTo and self.config.showGrid) then
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_13.."|cff00ff00"..MACAROON_STRINGS.BARTOOLTIP_1.."|r", MACAROON_STRINGS.BARTOOLTIP_14.."|cff00ff00On|r")
	elseif (not self.config.snapTo and self.config.showGrid) then
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_13.."|cfff00000"..MACAROON_STRINGS.BARTOOLTIP_2.."|r", MACAROON_STRINGS.BARTOOLTIP_14.."|cff00ff00On|r")
	elseif (self.config.snapTo and not self.config.showGrid) then
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_13.."|cff00ff00"..MACAROON_STRINGS.BARTOOLTIP_1.."|r", MACAROON_STRINGS.BARTOOLTIP_14.."|cfff00000Off|r")
	else
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_13.."|cfff00000"..MACAROON_STRINGS.BARTOOLTIP_2.."|r", MACAROON_STRINGS.BARTOOLTIP_14.."|cfff00000Off|r")
	end

	if (self.config.autoHide and self.config.target) then
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_15.."|cff00ff00"..MACAROON_STRINGS.BARTOOLTIP_1.."|r", MACAROON_STRINGS.BARTOOLTIP_16.."|cffffffff"..self.config.target.."|r")
	elseif (not self.config.autoHide and self.config.target) then
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_15.."|cfff00000"..MACAROON_STRINGS.BARTOOLTIP_2.."|r", MACAROON_STRINGS.BARTOOLTIP_16.."|cffffffff"..self.config.target.."|r")
	elseif (self.config.autoHide and not self.config.target) then
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_15.."|cff00ff00"..MACAROON_STRINGS.BARTOOLTIP_1.."|r", MACAROON_STRINGS.BARTOOLTIP_16.."|cffffffffnone|r")
	else
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_15.."|cfff00000"..MACAROON_STRINGS.BARTOOLTIP_2.."|r", MACAROON_STRINGS.BARTOOLTIP_16.."|cffffffffnone|r")
	end

	GameTooltip:AddDoubleLine(MACAROON_STRINGS.KEYBIND_TOOLTIP3..getBindkeyList(self).."|r")
	GameTooltip:AddDoubleLine(" ", " ")

	local state, count = self.handler:GetAttribute("state-current")
	if (state and MACAROON_STRINGS.STATES[state]) then
		if (self[state]) then
			count = self[state].buttonCount or "0"
		else
			count = "0"
		end
		GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_17.."|cff00ff00"..MACAROON_STRINGS.STATES[state].."|r", MACAROON_STRINGS.BARTOOLTIP_19.."|cff00ff00"..count.."|r")
	end

	GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_18.."|cff00ff00"..getStateList(self).."|r")
	GameTooltip:AddDoubleLine(" ", " ")
	GameTooltip:AddDoubleLine(MACAROON_STRINGS.BARTOOLTIP_20.."|cffffffff"..self.config.point.."|r"..MACAROON_STRINGS.BARTOOLTIP_21.."|cffffffff"..format("%.1f", self.config.x).."|r"..MACAROON_STRINGS.BARTOOLTIP_22.."|cffffffff"..format("%.1f", self.config.y).."|r")

	if (self.action) then

		GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_23)
		GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_28)
		GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_29)
		GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_30)
		GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_31)
	else
		if (self == Macaroon.CurrentBar) then
			GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_23)
			GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_24)
		else
			GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_25)
		end

		GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_26)
		GameTooltip:AddLine(MACAROON_STRINGS.BARTOOLTIP_27)
	end

	if (not self.selected) then
		if (self.config.hidden) then
			self:SetBackdropColor(1,0,0,0.6)
		else
			self:SetBackdropColor(0,0,1,0.4)
		end
		self.text:Show()
	end

	GameTooltip:Show()

	self.hover = true

end

function Macaroon.Bar_OnLeave(self)

	if (not self.selected) then
		if (self.config.hidden) then
			self:SetBackdropColor(1,0,0,0.4)
		else
			self:SetBackdropColor(0,0,0,0.2)
		end
		self.text:Hide()
	end

	GameTooltip:Hide()

	self.hover = nil
end

function Macaroon.Bar_OnUpdate(self, elapsed)

	if (self.elapsed) then

		self.elapsed = self.elapsed + elapsed

		if (self.elapsed > 10) then
			self.elapsed = 0.75
		end

		if (self.keydown and self.elapsed >= 0.5) then
			Macaroon.Bar_OnKeyDown(self, self.keydown, true)
		end

		if (self.hover) then
			self.elapsed = 0
		end

		if (self.selected and self.action and self.elapsed >= 0.4) then
			self.action = nil
			self:SetBackdropColor(0,0,1,0.4)
			self.message:SetText("")
		elseif (self.action and self.elapsed >= 0.4) then
			self.action = nil
			self:SetBackdropColor(0,0,0,0.2)
			self.message:SetText("")
		end

		if (self.action and self:GetButtonState() == "PUSHED") then

			self.pushed = self.pushed + elapsed

			if (self.pushed > 0.65) then

				if (self.click == "RightButton") then

					updateValues(self, -1, self.action)

				elseif (click == "MiddleButton") then

					self.hover = nil
					self.elapsed = 1
				else
					updateValues(self, 1, self.action)
				end
			end
		end

	end

	if (GetMouseFocus() == self) then
		self:EnableMouseWheel(true)
	else
		self:EnableMouseWheel(false)
	end
end

function Macaroon.Bar_OnShow(self)

	if (self.config and self.config.hidden) then
		if (not self.selected) then
			self:SetBackdropColor(1,0,0,0.5)
		else
			self:SetBackdropColor(1,0,0,0.6)
		end
	else
		if (not self.selected) then
			self:SetBackdropColor(0,0,0,0.2)
		else
			self:SetBackdropColor(0,0,1,0.4)
		end
	end

	if (not self.showgrid) then

		if (self.updateBar) then
			self.updateBar(self, nil, nil, true)
		end

		if (self.updateBarTarget) then
			self.updateBarTarget(self)
		end

		if (self.updateFunc) then
			self.updateFunc(self, self.handler:GetAttribute("state-current"))
		end
	end
end

function Macaroon.Bar_OnHide(self)

	if (not self.showgrid) then

		if (self.updateBarTarget) then
			self.updateBarTarget(self)
		end

		if (self.updateBarLink) then
			self.updateBarLink(self)
		end

		if (self.updateBarHidden) then
			self.updateBarHidden(self, nil, true)
		end

		if (self.updateFunc) then
			self.updateFunc(self, self.handler:GetAttribute("state-current"))
		end

		if (self.updateBar) then
			self.updateBar(self, nil, true, true)
		end

		self.click = nil
	end
end

function Macaroon.Bar_OnMouseWheel(self, delta)
	updateValues(self, delta, self.action)
end

function Macaroon.BarEditorCheck_OnClick(self, action)

	local bar, checked, index, state, frame = Macaroon.CurrentBar, self:GetChecked(), 1

	if (bar) then

		for k,v in pairs(barStates) do

			if (v[2] == action) then

				if (v[1] == "custom") then

					if (checked) then

						bar.config.custom = ""
						bar.config.customRange = ""
						bar.config.customNames = {}

						for kk,vv in pairs(barStates) do
							if (vv[1] ~= "custom") then
								bar.config[vv[1]] = false
							end
						end

					else
						bar.config.custom = false
						bar.config.customRange = false
						bar.config.customNames = false
					end
				else
					if (checked) then
						bar.config[v[1]] = true
						bar.config.custom = false
						bar.config.customRange = false
						bar.config.customNames = false
					else
						bar.config[v[1]] = false
					end
				end

				state = v[1]
			end
		end

		if (state) then

			if (state == "prowl") then

				if (not bar.stance or not bar.stance.registered) then
					self:SetChecked(nil)
					bar.config.prowl = false
					Macaroon.SetBarStates("stance", true, true)
				else
					bar.stance.registered = false
					Macaroon.SetBarStates("stance", true, true)
				end

				Macaroon.BarEditor_OnShow(self)
			else

				if (state == "custom") then
					if (bar.config.custom) then
						Macaroon.BarTextEditor_Toggle()
					end
					Macaroon.SetBarStates(state, true, true)
				else
					Macaroon.SetBarStates(state, true, true)
					Macaroon.BarEditor_OnShow(self)
				end
			end
		end

		updateCycleOrder(bar)
	end
end

function Macaroon.BarEditor_OnClick(self, action)

	PlaySound("gsTitleOptionOK")

	local bar = Macaroon.CurrentBar

	if (self.button == "close") then

		MacaroonBarEditor.shrink = true
		MacaroonBarTextEditor.shrink = true

	elseif (action) then

		bar.message:SetText(MACAROON_STRINGS.BAR_MESSAGE..MACAROON_STRINGS["BAR_EDIT_BUTTON_TEXT_"..self:GetID()].."|r")

		bar.action = action

		bar.hover = true

		bar:SetBackdropColor(0,1,0,0.4)
	end

	if (not ss.checkButtons[202]) then
		MacaroonBarEditor.shrink = true
		MacaroonBarTextEditor.shrink = true
	end
end

function Macaroon.BarEditor_OnEvent(self)

	local breakIndex, xOffset, index, frame, lastFrame, anchorFrame, lastButton, iOffset = 1, 15, 1

	if (UnitClass("player") == MACAROON_STRINGS.DRUID) then

		local origString, nextString = "prowl"

		while (MACAROON_STRINGS["BARSTATE_"..index]) do

			if (not barStates[index]) then
				barStates[index] = { "" }
			end

			index = index + 1
		end

		index = 3

		while (MACAROON_STRINGS["BARSTATE_"..index]) do

			nextString = barStates[index][1]

			barStates[index][1] = origString

			origString = nextString

			index = index + 1
		end
	end

	index = 1

	while (MACAROON_STRINGS["BARSTATE_"..index]) do
		barStates[index][2] = MACAROON_STRINGS["BARSTATE_"..index]
		index = index + 1
	end

	index = 1

	while (MACAROON_STRINGS["BAR_EDIT_BUTTON_"..breakIndex]) do
		breakIndex = breakIndex + 1
	end

	local yOffset = ((self:GetHeight()-42)-(breakIndex*20))/breakIndex+1

	while (MACAROON_STRINGS["BAR_EDIT_BUTTON_"..index]) do

		frame = CreateFrame("Button", "$parentButton"..index, self, "MacaroonButtonTemplate2")
		frame:SetID(index)
		frame:SetWidth(98)
		frame:SetHeight(20)
		frame:SetScript("OnClick", function(self, button) PlaySound("gsTitleOptionOK") Macaroon.BarEditor_OnClick(self, self.action) end)
		frame.text = _G[frame:GetName().."Text"]
		frame.text:SetText(MACAROON_STRINGS["BAR_EDIT_BUTTON_"..index])
		frame.action = frame.text:GetText()

		if (index == 1 or index == breakIndex) then
			if (anchorFrame) then
				frame:SetPoint("TOPLEFT", anchorFrame, "TOPRIGHT", 2, 0)
				anchorFrame = frame
				breakIndex = breakIndex + (breakIndex - 1)
			else
				frame:SetPoint("TOPLEFT", self, "TOPLEFT", xOffset, -15)
				anchorFrame = frame
			end
			lastFrame = frame
		else
			frame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -(yOffset))
			lastFrame = frame
		end

		lastButton = frame

		index = index + 1
	end

	breakIndex = 1; iOffset = 0

	while (MACAROON_STRINGS["BARSTATE_"..breakIndex]) do

		if (MACAROON_STRINGS["BARSTATE_"..breakIndex] == "exclude") then
			iOffset = iOffset + 1
		end

		breakIndex = breakIndex + 1
	end

	yOffset = ((self:GetHeight()-42)-(breakIndex*26))/breakIndex+1+iOffset

	xOffset, index, frame, lastFrame, anchorFrame, iOffset = -80, 1, nil, nil, nil, 0

	while (MACAROON_STRINGS["BARSTATE_"..index]) do

		if (MACAROON_STRINGS["BARSTATE_"..index] == "exclude") then

			iOffset = iOffset + 1

		else

			frame = CreateFrame("CheckButton", "$parentCheck"..index-iOffset, self, "MacaroonOptionCBTemplate")
			frame:SetID(index-iOffset)
			frame:SetScript("OnClick", function(self, button) PlaySound("gsTitleOptionOK") Macaroon.BarEditorCheck_OnClick(self, self.action)  end)
			frame.text = _G[frame:GetName().."Text"]
			frame.text:SetText(MACAROON_STRINGS["BARSTATE_"..index])
			frame.action = frame.text:GetText()

			if (index == 1 or index == breakIndex) then
				if (anchorFrame) then
					frame:SetPoint("TOPLEFT", anchorFrame, "TOPRIGHT", 2, 0)
					anchorFrame = frame
					breakIndex = breakIndex + (breakIndex - 1)
				else
					frame:SetPoint("TOPRIGHT", self, "TOPRIGHT", xOffset, -15)
					anchorFrame = frame
				end
				lastFrame = frame
			else
				frame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -(yOffset))
				lastFrame = frame
			end
		end

		index = index + 1
	end

	frame = CreateFrame("CheckButton", "$parentCheck"..index-iOffset, self, "MacaroonOptionCBTemplate")
	frame:SetID(index-iOffset)
	frame:SetScript("OnClick", function(self, button) PlaySound("gsTitleOptionOK") Macaroon.AutohideBar(nil, true, self:GetChecked()) Macaroon.BarEditor_OnShow(self) end)
	frame.text = _G[frame:GetName().."Text"]
	frame.text:SetText(MACAROON_STRINGS.BARSTATE_AH)
	frame.action = frame.text:GetText()
	frame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -(yOffset))
	lastFrame = frame

	index = index + 1

	frame = CreateFrame("CheckButton", "$parentCheck"..index-iOffset, self, "MacaroonOptionCBTemplate")
	frame:SetID(index-iOffset)
	frame:SetScript("OnClick", function(self, button) PlaySound("gsTitleOptionOK") Macaroon.ShowgridSet(nil, true, self:GetChecked()) Macaroon.BarEditor_OnShow(self) end)
	frame.text = _G[frame:GetName().."Text"]
	frame.text:SetText(MACAROON_STRINGS.BARSTATE_SG)
	frame.action = frame.text:GetText()
	frame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -(yOffset))
	lastFrame = frame

	index = index + 1

	frame = CreateFrame("CheckButton", "$parentCheck"..index-iOffset, self, "MacaroonOptionCBTemplate")
	frame:SetID(index-iOffset)
	frame:SetScript("OnClick", function(self, button) PlaySound("gsTitleOptionOK") Macaroon.SnapToBar(nil, true, self:GetChecked()) Macaroon.BarEditor_OnShow(self) end)
	frame.text = _G[frame:GetName().."Text"]
	frame.text:SetText(MACAROON_STRINGS.BARSTATE_ST)
	frame.action = frame.text:GetText()
	frame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -(yOffset))
	lastFrame = frame

	index = index + 1

	frame = CreateFrame("CheckButton", "$parentCheck"..index-iOffset, self, "MacaroonOptionCBTemplate")
	frame:SetID(index-iOffset)
	frame:SetScript("OnClick", function(self, button) PlaySound("gsTitleOptionOK") Macaroon.HideBar(nil, true, self:GetChecked()) Macaroon.BarEditor_OnShow(self) end)
	frame.text = _G[frame:GetName().."Text"]
	frame.text:SetText(MACAROON_STRINGS.BARSTATE_HD)
	frame.action = frame.text:GetText()
	frame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -(yOffset))
	lastFrame = frame

	self:Hide()
end

function Macaroon.BarEditor_OnShow(self)

	local bar, index, frame = Macaroon.CurrentBar, 1

	if (bar) then

		while (_G["MacaroonBarEditorCheck"..index]) do

			frame = _G["MacaroonBarEditorCheck"..index]

			for k,v in pairs(barStates) do
				if (v[2] == frame.action) then
					if (bar.config[v[1]]) then
						frame:SetChecked(1)
					else
						frame:SetChecked(nil)
					end
				end
			end

			for k,v in pairs(toggleStates) do
				if (v == frame.action) then
					if (bar.config[k]) then
						frame:SetChecked(1)
					else
						frame:SetChecked(nil)
					end
				end
			end

			index = index + 1
		end

		bar.action = nil
	end
end

function Macaroon.BarEditor_OnHide(self)

end

function Macaroon.BarEditor_OnUpdate(self)

	if (self.grow) then

		if (ss.checkButtons[203]) then

			if (self.scale < 1) then
				self.scale = self.scale + 0.1
				self:SetScale(self.scale)
			else
				self:SetScale(1)
				self.grow = false
			end
		else
			self:SetScale(1)
			self.grow = false
		end

	elseif (self.shrink) then

		if (ss.checkButtons[203]) then

			if (self.scale > 0.1) then
				self.scale = self.scale - 0.1
				self:SetScale(self.scale)
			else
				self:SetScale(0.01)
				self:Hide()
				self.shrink = false
			end
		else
			self:SetScale(0.01)
			self:Hide()
			self.shrink = false
		end
	end
end

function Macaroon.BarEditor_Toggle()

	local bar = Macaroon.CurrentBar

	MacaroonBarTextEditor.grow = false

	MacaroonBarTextEditor.shrink = true

	MacaroonBarEditor:ClearAllPoints()

	if (ss.checkButtons[202]) then
		MacaroonBarEditor:SetPoint("CENTER", MacaroonPanelMover, "CENTER")
	else
		MacaroonBarEditor:SetPoint("CENTER", bar, "CENTER")
	end

	MacaroonBarEditor:SetScale(0.01)

	MacaroonBarEditor.scale = 0.01

	MacaroonBarEditor.grow = true

	MacaroonBarEditor.shrink = false

	MacaroonBarEditor:Show()
end

function Macaroon.BarTextEditor_Toggle()

	local bar = Macaroon.CurrentBar

	MacaroonBarEditor.grow = false

	MacaroonBarEditor.shrink = true

	MacaroonBarTextEditor:ClearAllPoints()

	if (ss.checkButtons[202]) then
		MacaroonBarTextEditor:SetPoint("CENTER", MacaroonPanelMover, "CENTER")
	else
		MacaroonBarTextEditor:SetPoint("CENTER", bar, "CENTER")
	end

	MacaroonBarTextEditor:SetScale(0.01)

	MacaroonBarTextEditor.scale = 0.01

	MacaroonBarTextEditor.grow = true

	MacaroonBarTextEditor.shrink = false

	MacaroonBarTextEditor:Show()
end

function Macaroon.BarTextEditor_OnClick(self, action)

	PlaySound("gsTitleOptionOK")

	local bar = Macaroon.CurrentBar

	if (self.button == "close") then

	elseif (action) then

	end

	MacaroonBarTextEditor.shrink = true
end

local function nameEdit_OnTextChanged(self)

	if (MacaroonBarTextEditor.grow or MacaroonBarTextEditor.shrink) then
		return
	end

	local bar = Macaroon.CurrentBar

	if (bar and not MacaroonBarTextEditor.shrink and not MacaroonBarTextEditor.grow) then
		bar.config.name = self:GetText()
		bar.updateBar(bar, nil, nil, nil)
	end
end

local function target_OnShow(self)

	local bar = Macaroon.CurrentBar

	if (bar) then

		local data = {}

		for k,v in pairs(targetNames) do
			data[v] = k
		end

		Macaroon.EditBox_PopUpInitialize(self.popup, data)
	end

end

local function target_OnTextChanged(self)

	local bar = Macaroon.CurrentBar

	if (bar and not MacaroonBarTextEditor.shrink and not MacaroonBarTextEditor.grow) then

		if (self:GetText() == "-none-") then
			bar.config.target = false
		else
			bar.config.target = self:GetText()
		end

		if (bar.reaction) then
			bar.reaction.registered = false
		end
		bar.stateschanged = true
		bar.updateBar(bar, true)

		Macaroon.UpdateAutoMacros()
	end
end

local function linkedBar_OnShow(self)

	local bar = Macaroon.CurrentBar

	if (bar) then

		local data = { ["-none-"] = "none" }

		for k,v in pairs(Macaroon.BarIndexByName) do
			if (v ~= bar) then
				data[k] = v
			end
		end

		Macaroon.EditBox_PopUpInitialize(self.popup, data)
	end
end

local function linkedBar_OnTextChanged(self)

	local bar, stateString = Macaroon.BarIndexByName[self:GetText()]

	if (bar and not MacaroonBarTextEditor.shrink and not MacaroonBarTextEditor.grow) then

		local data = { ["-none-"] = "none" }

		for k,v in pairs(barStates) do

			if (bar.config[v[1]]) then

				for state, states in pairs(MACAROON_STRINGS.STATES) do

					stateString = match(state, "^%a+")

					if (stateString == v[1]) then
						data[states] = v[1]
					end
				end
			end

			if (managedStates[v[1]] and not managedStates[v[1]].homestate) then
				data[MACAROON_STRINGS.STATES.homestate] = v[1]
			end
		end

		Macaroon.EditBox_PopUpInitialize(self.statePopup.popup, data)
	end

	local text = self:GetText()

	bar = Macaroon.CurrentBar

	if (bar) then

		if (text == "-none-") then
			bar.config.barLink = false
			bar.config.showstates = false
			self.statePopup:SetText("-none-")
			Macaroon.EditBox_PopUpInitialize(self.statePopup.popup, nil)
		else
			bar.config.barLink = text
		end

		bar.updateBar(bar, true)
	end
end

local function linkedState_OnShow(self)

	local bar = Macaroon.CurrentBar

	if (bar) then
		if (bar.config.showstates) then
			self:SetText(bar.config.showstates)
		else
			self:SetText("-none-")
		end
	end
end

local function linkedState_OnTextChanged(self)

	local bar, text = Macaroon.CurrentBar, self:GetText()

	if (bar and not MacaroonBarTextEditor.shrink and not MacaroonBarTextEditor.grow) then

		if (text == "-none-") then
			bar.config.showstates = false
		else
			bar.config.showstates = text
		end

		bar.updateBar(bar, true, nil, nil)
	end

	self:SetCursorPosition(0)
end

local function barMap_OnShow(self)

	self.value = nil

	local bar = Macaroon.CurrentBar

	if (bar) then

		local data = {}

		for k,v in pairs(MACAROON_STRINGS.STATES) do

			if (bar.config.pagedbar and find(k, "pagedbar")) then

				data[v] = match(k, "%d+")

			elseif (bar.config.stance and find(k, "stance")) then

				data[v] = match(k, "%d+")

			end
		end

		Macaroon.EditBox_PopUpInitialize(self.popup, data)
	end

	self:SetText("")
end

local function barMap_OnTextChanged(self)

	local bar = Macaroon.CurrentBar

	if (bar and self.value and bar.config.remap and not MacaroonBarTextEditor.shrink and not MacaroonBarTextEditor.grow) then

		local map, remap

		for states in gmatch(bar.config.remap, "[^;]+") do

			map, remap = (":"):split(states)

			if (map == self.value) then

				MacaroonBarTextEditor.remapto.value = remap

				if (bar.config.pagedbar) then
					MacaroonBarTextEditor.remapto:SetText(MACAROON_STRINGS.STATES["pagedbar"..remap])
				elseif (bar.config.stance) then
					MacaroonBarTextEditor.remapto:SetText(MACAROON_STRINGS.STATES["stance"..remap])
				end
			end
		end
	else
		MacaroonBarTextEditor.remapto:SetText("")
	end

end

local function remapTo_OnShow(self)

	self.value = nil

	local bar = Macaroon.CurrentBar

	if (bar) then

		local data = {}

		for k,v in pairs(MACAROON_STRINGS.STATES) do

			if (bar.config.pagedbar and find(k, "pagedbar")) then

				data[v] = match(k, "%d+")

			elseif (bar.config.stance and find(k, "stance")) then

				data[v] = match(k, "%d+")

			end
		end

		Macaroon.EditBox_PopUpInitialize(self.popup, data)
	end
end

local function remapTo_OnTextChanged(self)

	local bar = Macaroon.CurrentBar

	if (bar and bar.config.remap and self.value and not MacaroonBarTextEditor.shrink and not MacaroonBarTextEditor.grow) then

		local value = MacaroonBarTextEditor.barmap.value

		bar.config.remap = gsub(bar.config.remap, value..":%d+", value..":"..self.value)

		if (bar.config.pagedbar) then
			bar.pagedbar.registered = false
		elseif (bar.config.stance) then
			bar.stance.registered = false
		end

		bar.stateschanged = true

		bar.updateBar(bar, true)
	end

end

local function customStates_OnShow(self)

end

local function customStates_Update(self)

	local bar = Macaroon.CurrentBar

	if (bar and bar.config.custom and self:GetText()) then

		local states = "custom "..self:GetText()

		states = gsub(states, "\n", ";"); states = gsub(states, "[;]+", ";")

		if (bar.custom) then
			bar.custom.registered = false
		end

		Macaroon.SetBarStates(states, true, true)

		updateCycleOrder(bar)
	end
end

local function expand_OnClick(self)

	PlaySound("gsTitleOptionOK")

	if (self.custom:GetWidth() < 499) then
		self.custom:SetWidth(500)
		self.edit:SetWidth(482)
		self:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Up")
		self:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Down")
	else
		self.custom:SetWidth(172)
		self.edit:SetWidth(158)
		self:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
		self:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Down")
	end
end

local function expand_OnShow(self)

	self:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
	self:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Down")
	self:SetDisabledTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Disabled")
	self:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
end

local function expand_OnHide(self)

	self.custom:SetWidth(172)
	self.edit:SetWidth(158)
	self:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
	self:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Down")
end

function Macaroon.BarTextEditor_OnEvent(self)

	local frame = CreateFrame("EditBox", "$parentNameEdit", self, "MacaroonEditBoxTemplate2")
	frame:SetWidth(110)
	frame:SetHeight(20)
	frame:SetTextInsets(7,3,0,0)
	frame:SetJustifyH("CENTER")
	frame.text:SetText(MACAROON_STRINGS.TEXTEDIT_NAME)
	frame:SetPoint("TOPRIGHT", -20, -20)
	frame:SetScript("OnTextChanged", nameEdit_OnTextChanged)
	self.name = frame

	frame = CreateFrame("EditBox", "$parentTarget", self, "MacaroonEditBoxTemplate1")
	frame:SetWidth(91)
	frame:SetHeight(20)
	frame:SetTextInsets(7,3,0,0)
	frame.text:SetText(MACAROON_STRINGS.TEXTEDIT_TARGET)
	frame:SetPoint("TOPRIGHT", "$parentNameEdit", "BOTTOMRIGHT", -18, -3)
	frame:SetScript("OnTextChanged", target_OnTextChanged)
	frame:SetScript("OnShow", target_OnShow)
	self.target = frame

	frame = CreateFrame("Frame", "$parentLinkedBG", self)
	frame:SetPoint("TOPLEFT", "$parentNameEdit", "TOPLEFT", -65, 5)
	frame:SetPoint("BOTTOMRIGHT", "$parentTarget", "BOTTOMRIGHT", 22, -5)
	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		tile = true,
		tileSize = 8,
		edgeSize = 18,
		insets = { left = 3, right = 3, top = 2, bottom = 2 },})
	frame:SetBackdropColor(0, 0, 0)
	frame:SetBackdropBorderColor(0.5, 0.5, 0.5)

	frame = CreateFrame("EditBox", "$parentLinkedState", self, "MacaroonEditBoxTemplate1")
	frame:SetWidth(91)
	frame:SetHeight(20)
	frame:SetTextInsets(7,3,0,0)
	frame.text:SetText(MACAROON_STRINGS.TEXTEDIT_LSTATE)
	frame:SetPoint("TOPRIGHT", "$parentTarget", "BOTTOMRIGHT", 0, -31)
	frame:SetScript("OnTextChanged", linkedState_OnTextChanged)
	frame:SetScript("OnShow", linkedState_OnShow)
	frame:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	self.linkstate = frame

	frame = CreateFrame("EditBox", "$parentLinkedBar", self, "MacaroonEditBoxTemplate1")
	frame:SetWidth(91)
	frame:SetHeight(20)
	frame:SetTextInsets(7,3,0,0)
	frame.text:SetText(MACAROON_STRINGS.TEXTEDIT_LTO)
	frame:SetPoint("TOPRIGHT", "$parentTarget", "BOTTOMRIGHT", 0, -11)
	frame:SetScript("OnTextChanged", linkedBar_OnTextChanged)
	frame:SetScript("OnShow", linkedBar_OnShow)
	frame:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	frame.statePopup = _G[self:GetName().."LinkedState"]
	self.linkbar = frame

	frame = CreateFrame("Frame", "$parentLinkedBG", self)
	frame:SetPoint("TOPLEFT", "$parentLinkedBar", "TOPLEFT", -65, 5)
	frame:SetPoint("BOTTOMRIGHT", "$parentLinkedState", "BOTTOMRIGHT", 22, -5)
	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		tile = true,
		tileSize = 8,
		edgeSize = 18,
		insets = { left = 3, right = 3, top = 2, bottom = 2 },})
	frame:SetBackdropColor(0, 0, 0)
	frame:SetBackdropBorderColor(0.5, 0.5, 0.5)

	frame = CreateFrame("EditBox", "$parentBarMap", self, "MacaroonEditBoxTemplate1")
	frame:SetWidth(91)
	frame:SetHeight(20)
	frame:SetTextInsets(7,3,0,0)
	frame.text:SetText(MACAROON_STRINGS.TEXTEDIT_BSTATE)
	frame:SetPoint("TOPRIGHT", "$parentLinkedState", "BOTTOMRIGHT", 0, -11)
	frame:SetScript("OnTextChanged", barMap_OnTextChanged)
	frame:SetScript("OnShow", barMap_OnShow)
	frame:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	self.barmap = frame

	frame = CreateFrame("EditBox", "$parentRemapTo", self, "MacaroonEditBoxTemplate1")
	frame:SetWidth(91)
	frame:SetHeight(20)
	frame:SetTextInsets(7,3,0,0)
	frame.text:SetText(MACAROON_STRINGS.TEXTEDIT_REMAP)
	frame:SetPoint("TOPRIGHT", "$parentBarMap", "BOTTOMRIGHT", 0, -3)
	frame:SetScript("OnTextChanged", remapTo_OnTextChanged)
	frame:SetScript("OnShow", remapTo_OnShow)
	frame:SetScript("OnEditFocusGained", function(self) self:ClearFocus() end)
	self.remapto = frame

	frame = CreateFrame("Frame", "$parentRemapBG", self)
	frame:SetPoint("TOPLEFT", "$parentBarMap", "TOPLEFT", -65, 5)
	frame:SetPoint("BOTTOMRIGHT", "$parentRemapTo", "BOTTOMRIGHT", 22, -5)
	frame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		tile = true,
		tileSize = 8,
		edgeSize = 18,
		insets = { left = 3, right = 3, top = 2, bottom = 2 },})
	frame:SetBackdropColor(0, 0, 0)
	frame:SetBackdropBorderColor(0.5, 0.5, 0.5)

	frame = CreateFrame("ScrollFrame", "$parentCustomStates", self, "MacaroonScrollFrameTemplate2")
	frame:SetWidth(172)
	frame:SetHeight(68)
	frame:SetToplevel(true)
	frame.edit:SetWidth(158)
	frame.edit:SetHeight(60)
	frame.edit:SetTextInsets(7,3,0,0)
	frame.text:ClearAllPoints()
	frame.text:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT", 18, 138)
	frame.text:SetText(MACAROON_STRINGS.TEXTEDIT_CUSTOM)
	frame:SetPoint("BOTTOM", -2, 54)
	self.custom = _G[self:GetName().."CustomStatesEdit"]

	frame = CreateFrame("Button", "$parentTextButton", self)
	frame:SetPoint("TOPLEFT", "$parentCustomStates")
	frame:SetPoint("BOTTOMRIGHT", "$parentCustomStates")
	frame.edit = _G[self:GetName().."CustomStatesEdit"]
	frame.edit:SetScript("OnEditFocusLost", customStates_Update)
	frame.edit:SetScript("OnShow", customStates_OnShow)
	frame.edit:SetScript("OnHide", customStates_Update)
	frame:SetScript("OnClick", function(self) self.edit:SetFocus() end)

	frame = CreateFrame("Frame", "$parentCustomStatesBG", self)
	frame:SetPoint("TOPLEFT", "$parentCustomStates", "TOPLEFT", 0, 15)
	frame:SetPoint("BOTTOMRIGHT", "$parentCustomStates", "BOTTOMRIGHT", 6, -15)
	frame:SetBackdrop({
		bgFile = "Interface\\ItemTextFrame\\ItemText-Stone-TopLeft",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		tile = true,
		tileSize = 8,
		edgeSize = 18,
		insets = { left = 3, right = 3, top = 2, bottom = 2 },})
	frame:SetBackdropColor(0, 0, 0)
	frame:SetBackdropBorderColor(0.5, 0.5, 0.5)

	frame = CreateFrame("Button", "$parentExpand", self)
	frame:SetWidth(20)
	frame:SetHeight(20)
	frame:SetPoint("BOTTOM", 79, 134)
	frame.text = frame:CreateFontString("$parentText", "ARTWORK", "GameFontNormalSmall")
	frame.text:SetText(MACAROON_STRINGS.MACRO_EXPAND)
	frame.text:SetTextHeight(9)
	frame.text:SetPoint("RIGHT", frame, "LEFT")
	frame.custom = _G[self:GetName().."CustomStates"]
	frame.edit = _G[self:GetName().."CustomStatesEdit"]
	frame:SetScript("OnClick", expand_OnClick)
	frame:SetScript("OnShow", expand_OnShow)
	frame:SetScript("OnHide", expand_OnHide)

	self:Hide()

end

local function updateText(frame, text)

	if (not frame or not text) then return end

	frame:SetText(text)
	frame:SetCursorPosition(0)
end

function Macaroon.BarTextEditor_OnShow(self)

	local bar = Macaroon.CurrentBar

	if (bar) then

		updateText(self.name, bar.config.name)

		if (bar.config.barLink) then
			updateText(self.linkbar, bar.config.barLink)
			updateText(self.linkstate, bar.config.showstates)
		else
			updateText(self.linkbar, "-none-")
			updateText(self.linkstate, "-none-")
		end

		if (bar.config.custom) then

			local string = ""

			for i=1,select('#',(";"):split(bar.config.custom)) do
				local text = gsub(select(i,(";"):split(bar.config.custom)), "%s+%S+$", "")
				text = gsub(text, "^%s+", "")
				string = string..text.."\n"
			end

			updateText(self.custom, string)

		else
			updateText(self.custom, "-none-")
		end

		if (bar.config.target) then
			updateText(self.target, bar.config.target)
		else
			updateText(self.target, "-none-")
		end

		self.backdrop:SetFrameLevel(0)
	end
end

function Macaroon.BarTextEditor_OnHide(self)

end

function Macaroon.BarTextEditor_OnUpdate(self)

	if (self.grow) then

		if (ss.checkButtons[203]) then

			if (self.scale < 1) then
				self.scale = self.scale + 0.1
				self:SetScale(self.scale)
			else
				self:SetScale(1)
				self.grow = false
			end
		else
			self:SetScale(1)
			self.grow = false
		end

	elseif (self.shrink) then

		if (ss.checkButtons[203]) then

			if (self.scale > 0.1) then
				self.scale = self.scale - 0.1
				self:SetScale(self.scale)
			else
				self:SetScale(0.01)
				self:Hide()
				self.shrink = false
			end
		else
			self:SetScale(0.01)
			self:Hide()
			self.shrink = false
		end
	end
end

function Macaroon.BarEditorPage_OnClick(parent)

	if (MacaroonBarTextEditor:IsVisible()) then

		Macaroon.BarEditor_Toggle()

	elseif (MacaroonBarEditor:IsVisible()) then

		Macaroon.BarTextEditor_Toggle()
	end
end

local function controlOnEvent(self, event, ...)

	if (event == "VARIABLES_LOADED") then

		ss = MacaroonSavedState

	elseif (event == "PLAYER_ENTERING_WORLD" and not playerEnteredWorld) then


		playerEnteredWorld = true

	elseif (event == "ACTIONBAR_SHOWGRID") then

		if (editMode) then
			for k,v in pairs(Macaroon.BarIndex) do
				if (v:IsVisible()) then
					v.showgrid = true
					v:Hide()
				end
			end
		end

	elseif (event == "ACTIONBAR_HIDEGRID") then

		if (editMode) then
			for k,v in pairs(Macaroon.BarIndex) do
				if (v.showgrid) then
					v:Show()
					v.showgrid = nil
				end
			end
		end
	end
end

local frame = CreateFrame("Frame", nil, UIParent)
frame:SetScript("OnEvent", controlOnEvent)
frame:RegisterEvent("VARIABLES_LOADED")
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("ACTIONBAR_SHOWGRID")
frame:RegisterEvent("ACTIONBAR_HIDEGRID")